package org.jsola.hr.common.wechat;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsola.common.DateKit;
import org.jsola.common.DateKit8;
import org.jsola.hr.constant.ConfigCodeConstants;
import org.jsola.hr.provider.IMessageProviderService;
import org.jsola.hr.provider.ISiteConfigProviderService;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.message.dto.WeiXinDTO;
import org.jsola.message.dto.WxMiNiParam;
import org.jsola.message.dto.WxTemplateParam;
import org.jsola.user.core.TokenUser;
import org.jsola.user.dao.IUnionOpenIdDAO;
import org.jsola.user.entity.UnionOpenIdDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 微信公众号推送事件
 */
@Slf4j
@Component
public class WeChatEvent {


    @Autowired
    private IUnionOpenIdDAO unionOpenIdDAO;

    @Autowired
    private MessageHandlerUtil messageHandlerUtil;

    @Autowired
    private ISiteConfigProviderService siteConfigProviderService;

    @Autowired
    private IMessageProviderService messageProviderService;

    @Autowired
    private IUserProviderService userProviderService;

    /**
     * 公众号类型
     */
    private static final String TYPE_ADMIN = "admin";


    /**
     * 根据不同情况选择相应的事件
     *
     * @param map      参数
     * @param account  账号
     * @param tenantId 租户id
     * @return 推送的信息
     */
    public String choose(Map<String, String> map, String tenantId, String account, String type) {
        String reslut = "";
        switch (map.get("Event")) {
            //模板消息回调
            case "TEMPLATESENDJOBFINISH":
                reslut = templateEndJobFinish(map);
                break;
            //用户订阅关注
            case "subscribe":
                reslut = subscribe(map, tenantId, account, type);
                break;
            //用户取消订阅关注
            case "unsubscribe":
                reslut = unsubscribe(map);
                break;
            //用户取消订阅关注
            case "SCAN":
                reslut = scan(map);
                break;
            default:
                break;

        }
        return reslut;
    }

    /**
     * 模板消息回调的事件
     *
     * @param map 参数
     * @return 推送的信息
     */
    private String templateEndJobFinish(Map<String, String> map) {
        if ("success".equals(map.get("Status"))) {
            log.info("模板消息推送成功,{}", map);
            //TODO 需要填写一个log日志
            return "success";
        } else {
            log.info("模板消息推送失败,{}", map);
            //TODO 需要填写一个log日志
            return "success";
        }
    }


    /**
     * 用户订阅事件公众号的事件
     *
     * @param map      参数
     * @param account  账户
     * @param tenantId 租户id
     * @param type 公众号类型（admin是管理端）
     * @return 推送的信息
     */
    private String subscribe(Map<String, String> map, String tenantId, String account, String type) {
        log.info("关注公众号，租户id：{}，账号：{}，type：{}", tenantId, account, type);
        String openid = map.get("FromUserName");
        log.info("微信信息反馈,{}", map);
        // 根据回调地址的type判断公众号是员工端还是管理端
        // 公众号appid ,appSecret
        String appid;
        String secret;
        if (Objects.equals(TYPE_ADMIN, type)) {
            appid = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_APPID_ADMIN, tenantId);
            secret = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_SECRET_ADMIN, tenantId);
        } else {
            appid = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_APPID, tenantId);
            secret = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_SECRET, tenantId);
        }
        //根据openId获取关注者的用户信息
        Map<String, Object> hashMap = messageHandlerUtil.getUserInfo(openid, appid, secret);
        String unionId = Objects.nonNull(hashMap.get("unionid")) ? hashMap.get("unionid").toString() : "";
        String nickName = Objects.nonNull(hashMap.get("nickname")) ? hashMap.get("nickname").toString() : "";
        log.info("用户关注公众号获取到unionId：{}", unionId);
        if (StringUtils.isNotBlank(unionId)) {
            // 处理用户openId与unionId绑定
            UnionOpenIdDO unionOpenIdDO = new UnionOpenIdDO();
            unionOpenIdDO.setAppId(appid);
            unionOpenIdDO.setOpenId(openid);
            unionOpenIdDO.setUnionId(unionId);
            int count = unionOpenIdDAO.selectCount(unionOpenIdDO);
            if (count == 0) {
                unionOpenIdDO.setSiteId("default");
                unionOpenIdDO.setCreateUserId("system");
                unionOpenIdDO.setGmtCreate(DateKit.getToday());
                unionOpenIdDAO.insertSelective(unionOpenIdDO);
            }
        }

        String buffer = "" + account + "欢迎您使用便捷的员工自助服务。您可以通过微信实现：" + "\n" +
                "> 员工信息完善" + "\n" +
                "> 合同签署" + "\n" +
                "> 发起请假等各类审批" + "\n" +
                "> 接收工资条" + "\n" +
                "> 接收公司公告及个人通知" + "\n" +
                "......" + "\n" +
                "现在就加入您所在的企业吧！" + "\n\n";
        String content = buffer.replaceAll("\n", "\n");
        String result = BuildWXMessage.buildTextMessage(map, content);
        try {
            sendTemplate(appid, nickName, tenantId, account, openid, type);
        } catch (Exception e) {
            log.error("用户关注公众号推送模板消息失败,原因:{}", e.getMessage());
        }
        log.info("微信关注公众号,推送信息,{}", result);
        return result;
    }

    private void sendTemplate(String appid, String nickName, String tenantId, String account, String openId, String type) {
        log.info("==========用户关注公众号推送模板消息:  appid:{},tenantId:{},openId:{}", appid, tenantId, openId);
        String templateId;
        if (Objects.equals(type, TYPE_ADMIN)) {
            templateId = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_SUBSCRIBE_TEMP_ID_ADMIN,
                    tenantId);
        } else {
            templateId = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_SUBSCRIBE_TEMP_ID,
                    tenantId);
        }
        // 推送绑定成功模板消息
        WeiXinDTO weiXinDTO = new WeiXinDTO();
        weiXinDTO.setAppId(appid);
        weiXinDTO.setTemplateId(templateId);
        weiXinDTO.setToUser(openId);
        // 拼装当前用户
        TokenUser tokenUser = new TokenUser();
        tokenUser.setSiteId("default");
        tokenUser.setUserId("system");

        List<WxTemplateParam> paramList = new ArrayList<>();
        WxTemplateParam param1 = new WxTemplateParam();
        param1.setName("first");
        param1.setValue("欢迎关注“" + account + "”公众号");
        paramList.add(param1);

        WxTemplateParam param2 = new WxTemplateParam();
        param2.setName("keyword1");
        param2.setValue("公众号关注");
        paramList.add(param2);

        WxTemplateParam param3 = new WxTemplateParam();
        param3.setName("keyword2");
        param3.setValue("公众号关注成功，可以前往小程序进行员工操作");
        paramList.add(param3);

        WxTemplateParam param4 = new WxTemplateParam();
        param4.setName("keyword3");
        param4.setValue(nickName);
        paramList.add(param4);

        WxTemplateParam param5 = new WxTemplateParam();
        param5.setName("keyword4");
        param5.setValue(DateKit8.getCurrentDay(DateKit8.DATE));
        paramList.add(param5);

        WxTemplateParam param6 = new WxTemplateParam();
        param6.setName("remark");
        param6.setValue("请点击跳转" + account + "小程序");
        paramList.add(param6);

        weiXinDTO.setTemplateParamList(paramList);
        // 跳转小程序
        WxMiNiParam wxMiNiParam = new WxMiNiParam();
        // 小程序appid
        String miniAppid = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_MINI_APPID, tenantId);
        // 小程序跳转首页
        String path = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_MINI_PAGE_PATH, tenantId);
        wxMiNiParam.setAppid(miniAppid);
        wxMiNiParam.setPagepath(path);
        weiXinDTO.setMiniProgram(wxMiNiParam);
        messageProviderService.sendWeChatTempMessage(weiXinDTO, tokenUser);
        log.info("==========用户关注公众号,主动推送模板信息{}", weiXinDTO.toString());
    }

    /**
     * 用户取消关注公众号的事件
     *
     * @param map 参数
     * @return 推送的信息
     */
    private String unsubscribe(Map<String, String> map) {
        log.info("用户取消关注公众号:{}", map);
        String openId = map.get("FromUserName");
        // 查询唯一记录并删除
        int count = userProviderService.deleteByOpenId(openId);
        log.info("用户取消关注删除unionOpenId,数量:{}", count);
        return "";
    }


    /**
     * 用户已关注时扫描二维码的事件
     *
     * @param map 参数
     * @return 推送的信息
     */
    private static String scan(Map<String, String> map) {
        String result = BuildWXMessage.buildTextMessage(map, "橙事薪人诚挚为您服务");
        log.info("用户已关注公众号,再次扫描:{}", map);
        return result;

    }
}
